<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>jsMind</title>
    <link type="text/css" rel="stylesheet" href="../style/jsmind.css" />
    <link type="text/css" rel="stylesheet" href="../style/niuxiaoma.css" />
    <script type="text/javascript" src="../es6/jsmind.js"></script>
    <script type="text/javascript" src="../es6/jsmind.draggable-node.js"></script>
    <script type="text/javascript" src="./tools.js"></script>
    <!-- <script type="text/javascript" src="../features/jsmind.shell.js"></script> -->
    <style>
        #jsmind_container {
            width: 800px;
            height: 500px;
        }
    </style>
</head>

<body>
    <div id="jsmind_container"></div>
    <div id="outZoomButton" class="circle">━</div>
    <div id="inZoomButton" class="circle">✚</div>
    <script>
        /**
* 计算C点坐标
* @param {Object} pointA - A点坐标 {x, y}
* @param {Object} pointB - B点坐标 {x, y}
* @param {number} yRatio - C点y坐标与A点y坐标的比值 (默认1.25)
* @param {number} angleDeg - AB与AC的夹角，单位度 (默认60)
* @returns {Object} C点坐标 {x, y}
*/
        function calculatePointC(pointA, pointB, yRatio = 0.25, angleDeg = 60) {
            // 将角度转换为弧度
            const angleRad = angleDeg * Math.PI / 180;

            // 计算向量AB
            const abVector = {
                x: pointB.x - pointA.x,
                y: pointB.y - pointA.y
            };

            // 计算AB的长度
            const abLength = Math.sqrt(abVector.x * abVector.x + abVector.y * abVector.y);

            // 计算C点的y坐标
            const cy = pointA.y + abLength * yRatio;

            // 计算AC的长度：使用三角函数关系 (cy - ay) = AC * sin(θ)
            const acLength = (cy - pointA.y) / Math.sin(angleRad);

            // 计算AC向量的x分量有两种可能（正负两种情况）
            const acX1 = Math.cos(angleRad) * acLength;
            const acX2 = -Math.cos(angleRad) * acLength;

            // 计算两种可能的C点坐标
            const c1 = { x: pointA.x + acX1, y: cy };
            const c2 = { x: pointA.x + acX2, y: cy };

            // 计算AB和AC的夹角，选择符合要求的解
            // 计算向量AC1和AC2
            const acVector1 = { x: c1.x - pointA.x, y: c1.y - pointA.y };
            const acVector2 = { x: c2.x - pointA.x, y: c2.y - pointA.y };

            // 计算点积和夹角
            const dotProduct1 = abVector.x * acVector1.x + abVector.y * acVector1.y;
            const angle1 = Math.acos(dotProduct1 / (abLength * acLength)) * 180 / Math.PI;

            const dotProduct2 = abVector.x * acVector2.x + abVector.y * acVector2.y;
            const angle2 = Math.acos(dotProduct2 / (abLength * acLength)) * 180 / Math.PI;

            // 返回与给定角度最接近的解
            return Math.abs(angle1 - angleDeg) < Math.abs(angle2 - angleDeg) ? c1 : c2;
        }

        // 使用示例
        // const pointA = { x: 0, y: 0 };
        // const pointB = { x: 10, y: 0 };
        // const pointC = calculatePointC(pointA, pointB, 1.25, 60);

        // console.log('C点坐标:', pointC);
    </script>
    <script>
        function polyline({ ctx, end_point, start_point }) {
            console.log('brokenline', ctx, start_point, end_point)
            const x1 = start_point.x;
            const y1 = start_point.y;
            const x2 = end_point.x;
            const y2 = end_point.y;
            ctx.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' H ' + x2 + ' V ' + y2);
        }
        function bezier_type1({ ctx, start_point, end_point }) {
            console.log('bezier_type1', ctx, start_point, end_point)
            const x1 = start_point.x;
            const y1 = start_point.y;
            const x2 = end_point.x;
            const y2 = end_point.y;
            var c1 = start_point
            if (y1 <= y2) {
                c1 = calculatePointC(start_point, end_point, -0.35, 45)
            } else {
                c1 = calculatePointC(start_point, end_point, 0.35, 45)
            }
            var c2 = end_point
            ctx.setAttribute('d', `M${x1},${y1} C${c1.x},${c1.y} ${c2.x},${c2.y} ${x2},${y2}`);
        }
        function bezier_type2({ ctx, start_point, end_point }) {
            console.log('bezier_type2', ctx, start_point, end_point)
            const x1 = start_point.x;
            const y1 = start_point.y;
            const x2 = end_point.x;
            const y2 = end_point.y;
            // 计算向量AB
            const abVector = {
                x: x2 - x1,
                y: y2 - y1
            };
            // 计算AB的长度
            const abLength = Math.sqrt(abVector.x * abVector.x + abVector.y * abVector.y);
            const s1 = abLength * 0.02
            const s2 = abLength * 0.05
            console.log('abLength', abLength)
            var c1 = { ...start_point }
            var c2 = { ...end_point }
            var b1 = Math.sqrt(abLength * .20 * abLength * .20 - s1 * s1);
            var b2 = Math.sqrt(abLength * .40 * abLength * .40 - s2 * s2);

            if (y1 > y2 && x1 > x2) {
                c1.y = c1.y + s1
                c1.x = c1.x - b1
                c2.x = c2.x + s2
                c2.y = c2.y + b2
            }
            if (y1 < y2 && x1 > x2) {
                c1.y = c1.y - s1
                c1.x = c1.x - b1
                c2.x = c2.x + s2
                c2.y = c2.y - b2
            }
            if (y1 < y2 && x1 < x2) {
                c1.y = c1.y - s1
                c1.x = c1.x + b1
                c2.x = c2.x - s2
                c2.y = c2.y - b2
            }
            if (y1 > y2 && x1 < x2) {
                c1.y = c1.y + sy1
                c1.x = c1.x + b1
                c2.x = c2.x - sy2
                c2.y = c2.y + b2
            }
            // console.log('findNewControlPoints', c1, c2)
            if (y1 == y2 || x1 == x2) {
                ctx.setAttribute('d', 'M ' + x1 + ' ' + y1 + ' L ' + x2 + ' ' + y2);
            } else {
                ctx.setAttribute('d', `M${x1},${y1} C${c1.x},${c1.y} ${c2.x},${c2.y} ${x2},${y2}`);
            }

        }
        var _jm = null;
        function load_jsmind() {
            var mind = {
                meta: {
                    name: 'demo',
                    author: 'hizzgdev@163.com',
                    version: '0.2',
                },
                format: 'node_array',
                data: [
                    { id: 'root', isroot: true, topic: 'LLM × MapReduce-V2: Entropy-Driven Convolutional Test-Time Scaling for Generating Long-Form Articles from Extremely Long Resources' },

                    { id: 'sub1', parentid: 'root', topic: 'sub1' },
                    { id: 'sub11', parentid: 'sub1', topic: '提出LLM × MapReduce-V2框架' },
                    { id: 'sub12', parentid: 'sub1', topic: 'sub12' },
                    { id: 'sub13', parentid: 'sub1', topic: 'sub13' },

                    { id: 'sub2', parentid: 'root', topic: 'sub2' },
                    { id: 'sub21', parentid: 'sub2', topic: 'sub21' },
                    { id: 'sub22', parentid: 'sub2', topic: 'sub22' },

                    { id: 'sub3', parentid: 'root', topic: 'sub3' },
                    { id: 'sub4', parentid: 'root', topic: 'sub4' },
                    { id: 'sub5', parentid: 'root', topic: 'sub5' },
                    { id: 'sub6', parentid: 'root', topic: 'sub6' },
                    { id: 'sub7', parentid: 'root', topic: 'sub7' },
                ],
            };
            var options = {
                container: 'jsmind_container',
                editable: false,
                theme: 'niuxiaoma',
                log_level: 'debug',
                view: {
                    draggable: true,
                    hide_scrollbars_when_draggable: true,
                    node_overflow: 'wrap',
                    hmargin: 0,
                    vmargin: 0,
                    engine: 'svg',
                    line_width: 1,
                    line_color: '#555',
                    // line_style: 'straight',
                    custom_line_render: bezier_type2
                },
                layout: {
                    pspace: 16
                }
            };
            _jm = new jsMind(options);
            _jm.show(mind);
            console.log(_jm)
            // jm.set_readonly(true);
            // var mind_data = jm.get_data();
            // alert(mind_data);
        }
        load_jsmind()
    </script>
    <script>
        function outZoom() {
            if (_jm) {
                console.log(_jm)
                _jm.view.zoom_out()
            }
        }
        function inZoom() {
            if (_jm) {
                console.log(_jm)
                _jm.view.zoom_in()
            }
        }
        const outZoomButton = document.getElementById('outZoomButton');
        const inZoomButton = document.getElementById('inZoomButton');
        outZoomButton.addEventListener('click', outZoom);
        inZoomButton.addEventListener('click', inZoom);

    </script>
</body>

</html>